package api

import (
	"encoding/json"
	"fmt"
	"strconv"

	"github.com/EDDYCJY/go-gin-example/models"
	"github.com/EDDYCJY/go-gin-example/pkg/app"
	"github.com/EDDYCJY/go-gin-example/pkg/e"
	"github.com/EDDYCJY/go-gin-example/pkg/util"
	"github.com/gin-gonic/gin"
)

// 查询task列表
type TaskListReq struct {
	NodeID string `form:"node_id" binding:"required"`
	TaskID string `form:"task_id"`
}

func Handle_TaskList(c *gin.Context) {
	appG := app.Gin{C: c}

	var req TaskListReq
	if err := c.ShouldBindQuery(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	api := fmt.Sprintf("/api/v1/task/list?node_id=%v", req.NodeID)
	if len(req.TaskID) > 0 {
		api = fmt.Sprintf("/api/v1/task/list?node_id=%v&task_id=%v", req.NodeID, req.TaskID)
	}

	user_account, ferror := models.GetAccountByUserId(uint64(c.GetInt64("user_id")))
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_wallet_sign, ferror := util.GenWalletSign(user_account.WalletAddr, user_account.PrivateKey)
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_request, _ := json.Marshal(params_wallet_sign)

	data := util.PostRequest(api, params_request)
	if data.Errcode != 0 {
		appG.ResponseError(data.Errcode, data.Errmsg)
	} else {
		appG.ResponseSuccess(data.Data)
	}
}

// 创建虚拟机
type TaskCreateReq struct {
	ImageName string `json:"image_name" binding:"required"`
	OS        string `json:"os" binding:"required"`
	BiosMode  string `json:"bios_mode" binding:"required"`
	SshPort   uint32 `json:"ssh_port"`
	RdpPort   uint32 `json:"rdp_port"`
	VncPort   uint32 `json:"vnc_port" binding:"gte=1"`
	CpuCores  uint32 `json:"cpu_cores" binding:"gte=1"`
	MemSize   uint64 `json:"mem_size" binding:"gte=1"`
	GpuCount  uint32 `json:"gpu_count" binding:"required"`
	DiskSize  uint64 `json:"disk_size" binding:"gte=1"`
	Desc      string `json:"desc"`
}

func Handle_TaskCreate(c *gin.Context) {
	appG := app.Gin{C: c}

	var req TaskCreateReq
	if err := c.ShouldBindJSON(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	api := fmt.Sprintf("/api/v1/task/create?node_id=%v", c.DefaultQuery("node_id", ""))

	user_account, ferror := models.GetAccountByUserId(uint64(c.GetInt64("user_id")))
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_wallet_sign, ferror := util.GenWalletSign(user_account.WalletAddr, user_account.PrivateKey)
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}

	params := map[string]string{
		"image_name": req.ImageName,
		"os":         req.OS,
		"bios_mode":  req.BiosMode,
		"ssh_port":   strconv.Itoa(int(req.SshPort)),
		"rdp_port":   strconv.Itoa(int(req.RdpPort)),
		"vnc_port":   strconv.Itoa(int(req.VncPort)),
		"cpu_cores":  strconv.Itoa(int(req.CpuCores)),
		"mem_size":   strconv.FormatInt(int64(req.MemSize), 10),
		"gpu_count":  strconv.Itoa(int(req.GpuCount)),
		"disk_size":  strconv.FormatInt(int64(req.DiskSize), 10),
		"desc":       req.Desc,
	}
	for k, v := range params_wallet_sign {
		params[k] = v
	}
	params_request, _ := json.Marshal(params)

	data := util.PostRequest(api, params_request)
	if data.Errcode != 0 {
		appG.ResponseError(data.Errcode, data.Errmsg)
	} else {
		appG.ResponseSuccess(data.Data)
	}
}

// 启动虚拟机
type TaskStartReq struct {
	NodeID string `form:"node_id" binding:"required"`
	TaskID string `form:"task_id" binding:"required"`
}

func Handle_TaskStart(c *gin.Context) {
	appG := app.Gin{C: c}

	var req TaskStartReq
	if err := c.ShouldBindQuery(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	api := fmt.Sprintf("/api/v1/task/start?node_id=%v&task_id=%v", req.NodeID, req.TaskID)

	user_account, ferror := models.GetAccountByUserId(uint64(c.GetInt64("user_id")))
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_wallet_sign, ferror := util.GenWalletSign(user_account.WalletAddr, user_account.PrivateKey)
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_request, _ := json.Marshal(params_wallet_sign)

	data := util.PostRequest(api, params_request)
	if data.Errcode != 0 {
		appG.ResponseError(data.Errcode, data.Errmsg)
	} else {
		appG.ResponseSuccess(data.Data)
	}
}

// 关闭虚拟机
type TaskShutdownReq struct {
	NodeID string `form:"node_id" binding:"required"`
	TaskID string `form:"task_id" binding:"required"`
}

func Handle_TaskShutdown(c *gin.Context) {
	appG := app.Gin{C: c}

	var req TaskShutdownReq
	if err := c.ShouldBindQuery(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	api := fmt.Sprintf("/api/v1/task/shutdown?node_id=%v&task_id=%v", req.NodeID, req.TaskID)

	user_account, ferror := models.GetAccountByUserId(uint64(c.GetInt64("user_id")))
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_wallet_sign, ferror := util.GenWalletSign(user_account.WalletAddr, user_account.PrivateKey)
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_request, _ := json.Marshal(params_wallet_sign)

	data := util.PostRequest(api, params_request)
	if data.Errcode != 0 {
		appG.ResponseError(data.Errcode, data.Errmsg)
	} else {
		appG.ResponseSuccess(data.Data)
	}
}

// 强制关闭虚拟机
type TaskPoweroffReq struct {
	NodeID string `form:"node_id" binding:"required"`
	TaskID string `form:"task_id" binding:"required"`
}

func Handle_TaskPoweroff(c *gin.Context) {
	appG := app.Gin{C: c}

	var req TaskPoweroffReq
	if err := c.ShouldBindQuery(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	api := fmt.Sprintf("/api/v1/task/poweroff?node_id=%v&task_id=%v", req.NodeID, req.TaskID)

	user_account, ferror := models.GetAccountByUserId(uint64(c.GetInt64("user_id")))
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_wallet_sign, ferror := util.GenWalletSign(user_account.WalletAddr, user_account.PrivateKey)
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_request, _ := json.Marshal(params_wallet_sign)

	data := util.PostRequest(api, params_request)
	if data.Errcode != 0 {
		appG.ResponseError(data.Errcode, data.Errmsg)
	} else {
		appG.ResponseSuccess(data.Data)
	}
}

// 重启虚拟机
type TaskRestartReq struct {
	NodeID string `form:"node_id" binding:"required"`
	TaskID string `form:"task_id" binding:"required"`
	Force  string `form:"force"`
}

func Handle_TaskRestart(c *gin.Context) {
	appG := app.Gin{C: c}

	var req TaskRestartReq
	if err := c.ShouldBindQuery(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	api := fmt.Sprintf("/api/v1/task/restart?node_id=%v&task_id=%v", req.NodeID, req.TaskID)
	if len(req.Force) > 0 {
		api = fmt.Sprintf("/api/v1/task/restart?node_id=%v&task_id=%v&force=%v",
			req.NodeID, req.TaskID, req.Force)
	}

	user_account, ferror := models.GetAccountByUserId(uint64(c.GetInt64("user_id")))
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_wallet_sign, ferror := util.GenWalletSign(user_account.WalletAddr, user_account.PrivateKey)
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_request, _ := json.Marshal(params_wallet_sign)

	data := util.PostRequest(api, params_request)
	if data.Errcode != 0 {
		appG.ResponseError(data.Errcode, data.Errmsg)
	} else {
		appG.ResponseSuccess(data.Data)
	}
}

// 删除虚拟机
type TaskDeleteReq struct {
	OrderID uint64 `form:"order_id" binding:"required"`
	NodeID  string `form:"node_id" binding:"required"`
	TaskID  string `form:"task_id" binding:"required"`
}

func Handle_TaskDelete(c *gin.Context) {
	appG := app.Gin{C: c}

	var req TaskDeleteReq
	if err := c.ShouldBindQuery(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	api := fmt.Sprintf("/api/v1/task/delete?node_id=%v&task_id=%v", req.NodeID, req.TaskID)

	user_account, ferror := models.GetAccountByUserId(uint64(c.GetInt64("user_id")))
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_wallet_sign, ferror := util.GenWalletSign(user_account.WalletAddr, user_account.PrivateKey)
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_request, _ := json.Marshal(params_wallet_sign)

	rent_order, ferror := models.GetRentOrderByID(req.OrderID)
	if rent_order != nil && rent_order.RentType == 1 { //整机
		data := util.PostRequest(api, params_request)
		if data.Errcode != 0 {
			appG.ResponseError(data.Errcode, data.Errmsg)
		} else {
			appG.ResponseSuccess(data.Data)
		}
	} else { //虚拟机
		appG.ResponseError(e.ERROR, "不能删除")
	}
}

// 修改虚拟机密码
type TaskPasswdSetReq struct {
	Username  string `json:"username" binding:"required"`
	NewPasswd string `json:"new_passwd" binding:"required"`
}

func Handle_TaskPasswdSet(c *gin.Context) {
	appG := app.Gin{C: c}

	var req TaskPasswdSetReq
	if err := c.ShouldBindJSON(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	api := fmt.Sprintf("/api/v1/task/passwd/set?node_id=%v&task_id=%v",
		c.DefaultQuery("node_id", ""), c.DefaultQuery("task_id", ""))

	accountInfo, ferror := models.GetAccountByUserId(uint64(c.GetInt64("user_id")))
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params1, ferror := util.GenWalletSign(accountInfo.WalletAddr, accountInfo.PrivateKey)
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}

	params2 := map[string]string{
		"user_name": req.Username,
		"passwd":    req.NewPasswd,
	}

	for k, v := range params1 {
		params2[k] = v
	}
	params, _ := json.Marshal(params2)

	data := util.PostRequest(api, params)
	if data.Errcode != 0 {
		appG.ResponseError(data.Errcode, data.Errmsg)
	} else {
		appG.ResponseSuccess(data.Data)
	}
}

// 修改虚拟机配置信息
type TaskModifyReq struct {
	NewSshPort  uint32 `json:"new_ssh_port"`
	NewRdpPort  uint32 `json:"new_rdp_port"`
	NewVncPort  uint32 `json:"new_vnc_port"`
	NewGpuCount uint32 `json:"new_gpu_count"`
	NewCpuCores uint32 `json:"new_cpu_cores"`
	NewMemSize  uint64 `json:"new_mem_size"`
}

func Handle_TaskModify(c *gin.Context) {
	appG := app.Gin{C: c}

	var req TaskModifyReq
	if err := c.ShouldBindJSON(&req); err != nil {
		appG.ResponseError(e.ERROR, "请求参数错误:"+err.Error())
		return
	}

	var param_order_id, _ = strconv.ParseUint(c.DefaultQuery("order_id", ""), 10, 64)
	var param_node_id = c.DefaultQuery("node_id", "")
	var param_task_id = c.DefaultQuery("task_id", "")

	api := fmt.Sprintf("/api/v1/task/modify?node_id=%v&task_id=%v",
		param_node_id, param_task_id)

	user_account, ferror := models.GetAccountByUserId(uint64(c.GetInt64("user_id")))
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}
	params_wallet_sign, ferror := util.GenWalletSign(user_account.WalletAddr, user_account.PrivateKey)
	if ferror.ErrCode != e.SUCCESS {
		appG.ResponseError(ferror.ErrCode, ferror.ErrMsg)
		return
	}

	rent_order, ferror := models.GetRentOrderByID(param_order_id)
	if rent_order == nil || rent_order.RentType != 1 { //不是整机
		appG.ResponseError(e.ERROR, "不能修改")
		return
	}

	var params2 = map[string]string{}
	params2["new_ssh_port"] = strconv.Itoa(int(req.NewSshPort))
	params2["new_rdp_port"] = strconv.Itoa(int(req.NewRdpPort))
	params2["new_vnc_port"] = strconv.Itoa(int(req.NewVncPort))
	params2["new_gpu_count"] = strconv.Itoa(int(req.NewGpuCount))
	params2["new_cpu_cores"] = strconv.Itoa(int(req.NewCpuCores))
	params2["new_mem_size"] = strconv.FormatUint(req.NewMemSize, 10)

	for k, v := range params_wallet_sign {
		params2[k] = v
	}
	params, _ := json.Marshal(params2)

	data := util.PostRequest(api, params)
	if data.Errcode != 0 {
		appG.ResponseError(data.Errcode, data.Errmsg)
	} else {
		appG.ResponseSuccess(data.Data)
	}
}
